<template>
  <div class="o-filter-input" :style="filterStyle">
    <div class="btns">
      <ButtonGroup size="small">
        <Button @click="allSelect" type="text">
          {{ $srv.getI18nByPath('others.selectall') }}
        </Button>
        <Button @click="notAllSelect" type="text">
          {{ $srv.getI18nByPath('others.nselectall') }}
        </Button>
        <Button @click="reverseSelect" type="text">
          {{ $srv.getI18nByPath('others.rselect') }}
        </Button>
      </ButtonGroup>
    </div>
    <div class="search-key">
      <Input
        v-model="searchKey"
        icon="ios-search-outline"
        :placeholder="$srv.getI18nByPath('others.entersearch')"
        clearable
        @on-change="singlesFilter"
      />
    </div>
    <div class="y-scroll checks">
      <div
        v-for="s in singles"
        :key="s.label"
        :title="$srv.getI18nBySrv(s.label)"
      >
        <Checkbox
          class="chk"
          v-show="s.isShow"
          v-model="s.isChk"
          @on-change="onsinglesChange"
        >
          {{ $srv.getI18nBySrv(s.label) }}
        </Checkbox>
      </div>
    </div>
    <div style="height: 10px"></div>
  </div>
</template>

<script lang="ts">
import { Tsrv } from '@/services';
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';

@Component
export default class oFilterInput extends Vue {
  public compName: string = 'oFilterInput';

  @Prop() params: any;

  private searchKey = '';

  private singles = [];

  private column = null;

  private shouEd = false;

  private option = null;

  private type = 'string';

  private renderType = 'string';

  private condition = '=';

  private loading = false;

  private list = [];

  private selectedList = [1, 2, 3];

  private value = null;

  private filterStyle = {};

  private singlesFilter() {
    if (this.searchKey === '') {
      this.singles.forEach(e => {
        e.isShow = true;
      });
    } else {
      this.singles.forEach(e => {
        if (Tsrv.getI18nBySrv(e.label).indexOf(this.searchKey) !== -1) {
          e.isShow = true;
        } else {
          e.isShow = false;
        }
      });
    }
  }

  @Watch('params')
  onParamsChange() {
    this.load();
  }

  @Watch('params.column.property')
  onParamsChanges() {
    this.params.column.params
      .loadFilterList(this.params.column.property)
      .then(data => {
        this.loading = false;
        if (Tsrv.utils.isArray(data)) {
          this.list = data;
          Tsrv.utils.clear(this.singles);
          this.list.forEach(e => {
            const v: any = e.virtualValue ? e.virtualValue : e.value;
            this.singles.push({
              label: `${v}`,
              value: v,
              filterField: e.field,
              filterValue: e.value,
              isChk: false,
              isShow: true
            });
          });
          this.params.column.params.loadedFilterList = data;
          this.updateInputStyle();
        }
      })
      .catch(() => {
        this.loading = false;
      });
  }

  created() {
    this.init();
    this.load();
  }

  mounted() {
    if (this.params.column.params.filters.length <= 0) {
      this.params.column.params
        .loadFilterList(this.params.column.property)
        .then(data => {
          this.loading = false;
          if (Tsrv.utils.isArray(data)) {
            this.list = data;
            this.list.forEach(e => {
              const v: any = e.virtualValue ? e.virtualValue : e.value;
              this.singles.push({
                label: `${v}`,
                value: v,
                filterField: e.field,
                filterValue: e.value,
                isChk: false,
                isShow: true
              });
            });
            this.params.column.params.loadedFilterList = data;
          }
        })
        .catch(() => {
          this.loading = false;
        });
    } else {
      this.singles = this.params.column.params.filters;
    }
    this.$nextTick(() => {
      this.updateInputStyle();
    });
    if (this.searchKey === '' && !this.singles.some(el => el.isChk)) {
      this.singlesFilter();
    }
  }

  beforeDestroy() {
    if (
      this.params.column.params.loadedFilterList &&
      this.params.column.params.loadedFilterList.length > 0
    ) {
      this.params.column.params.loadedFilterList = Tsrv.utils.clone(
        this.selectedList
      );
    }
  }

  /**
   * 更新字段筛选框高度
   */
  private updateInputStyle() {
    const parent = this.$el.parentElement;
    const filterContent = parent?.parentElement ?? null;
    const vxeTable: HTMLElement | null =
      parent?.parentElement?.parentElement ?? null;
    if (!Tsrv.noValue(filterContent) && !Tsrv.noValue(vxeTable)) {
      parent.style.maxHeight = `${vxeTable.offsetHeight - 68}px`;
      this.filterStyle = {
        maxHeight: parent.style.maxHeight
      };
    }
  }

  private allSelect() {
    this.singles.forEach(e => {
      // e.val = true;
      e.isChk = true;
    });
    this.onsinglesChange();
  }

  private notAllSelect() {
    this.singles.forEach(e => {
      // e.val = false;
      e.isChk = false;
    });
    this.onsinglesChange();
  }

  private reverseSelect() {
    this.singles.forEach(e => {
      e.isChk = !e.isChk;
    });
    this.onsinglesChange();
  }

  onsinglesChange() {
    this.params.column.params.filters = this.singles;
    const isSelect = !!this.singles.find(ele => ele.isChk === true);
    this.params.$panel.changeOption(
      null,
      isSelect,
      this.params.column.filters[0]
    );
  }

  private changeCondition(con: any) {
    if (['datetime', 'date', 'time', 'number'].indexOf(this.type) > -1) {
      if (con === ':') {
        this.value = ['', ''];
        this.renderType = `${this.type}range`;
      } else {
        if (this.condition === ':') {
          this.renderType = this.type;
          this.value = '';
        }
      }
    }
    this.condition = con;
    this.changeOptionEvent();
  }

  private inputChange() {
    this.selectedList = [];
    this.params.column.params.loadedFilterList = [];
    this.changeOptionEvent();
  }

  private dateChange(value: any) {
    this.value = value;
    this.selectedList = [];
    this.params.column.params.loadedFilterList = [];
    this.changeOptionEvent();
  }

  private loadMultiList() {
    if (
      (this.list.length === 0 ||
        this.selectedList.length === this.list.length) &&
      !this.loading
    ) {
      this.loading = true;
      this.params.column.params
        .loadFilterList(this.params.column.property)
        .then(data => {
          this.loading = false;
          if (Tsrv.utils.isArray(data)) {
            this.list = data;
            this.params.column.params.loadedFilterList = data;
          }
        })
        .catch(() => {
          this.loading = false;
        });
    }
    this.$nextTick(() => {
      this.updateInputStyle();
    });
  }

  private selectMultiList() {
    this.changeOptionEvent();
  }

  private init() {
    const { column } = this.params;
    const info = Tsrv.utils.getColumnType(column);
    if (info.name) {
      if (info.name === 'oDatePicker' || info.name === 'oNumberInput') {
        this.condition = '=';
      } else {
        this.condition = 'custom';
      }
      this.type = info.type;
      this.renderType = info.renderType;
    }
  }

  private load() {
    const { column } = this.params;
    const option = column.filters[0];
    this.column = column;
    this.option = option;

    const { data, list } = option;
    if (data) {
      this.condition = data.condition || '=';
      this.value = data.value;
      this.changeOptionEvent();
    }

    if (list) {
      this.selectedList = list;
    }

    this.list = this.params.column.params.loadedFilterList || [];
  }

  private replaceSensitive(value) {
    if (typeof value === 'string') {
      return (
        value
          .replace(/,/g, '\\,')
          .replace(/:/g, '\\:')
          // .replace(/\|/g, "\\|")
          .replace(/\*/g, '\\*')
      );
    }
    return value;
  }

  private changeOptionEvent() {
    const { params, option } = this;
    const { $panel } = params;
    option.advance = {};
    option.list = [];
    if (this.selectedList.length === 0) {
      option.data = {
        ...Tsrv.utils.valueToFilter(
          this.type,
          this.condition,
          this.value ? this.replaceSensitive(this.value) : this.value
        ),
        aas: 123
      };
      option.advance = Tsrv.utils.valueToFilter(
        this.type,
        this.condition,
        this.value
      );
    } else {
      option.data = {
        ...Tsrv.utils.valueToFilter(
          'string',
          'custom',
          this.selectedList
            .map(el => {
              return this.replaceSensitive(el);
            })
            .join('|')
        ),
        aas: 123
      };
      option.list = this.selectedList;
    }
    option.aas = '123';
    const checked = !!option.data;
    $panel.changeOption(null, checked, option);
  }

  private keyupEvent({ $event }) {
    const { params } = this;
    const { $panel } = params;
    if ($event.keyCode === 13) {
      $panel.confirmFilter();
    }
  }
}
</script>

<style lang="scss" scoped>
.o-filter-input {
  padding: 6px;
  max-width: 240px;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  .btns {
    border-bottom: 1px solid #cccccc;
    width: 100%;
    text-align: center;
    padding: 5px 0px;
  }
  .search-key {
    width: 100%;
    ::v-deepinput {
      border-radius: unset;
    }
  }
  .checks {
    // max-height: 240px;
    padding: 0px 15px;
    flex: 1;
    .chk {
      margin: 6px 0px;
      overflow: hidden;
      text-overflow: ellipsis;
      width: 100%;
      white-space: nowrap;
    }
  }
  .filter-multi {
    padding-bottom: 5px;
    ::v-deep .ivu-select {
      .ivu-select-selection {
        max-height: 140px;
        overflow-y: auto;
        &::-webkit-scrollbar {
          width: 6px;
          background: #f5f5f5;
          border-radius: 6px;
        }
        &::-webkit-scrollbar-track-piece {
          background: #fff;
          border-radius: 6px;
        }
        &::-webkit-scrollbar-thumb {
          background: #b1b1b1;
          border-radius: 6px;
        }
      }
    }
  }
  .title {
    padding: 5px 0;
    color: #999;
  }
  .filters {
    width: 220px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 100%;
    padding-bottom: 5px;
    .ivu-radio-group ::v-deep {
      .ivu-radio-inner::after {
        border-radius: 100%;
      }
    }
    .ivu-input-wrapper,
    .ivu-date-picker {
      margin-top: 10px;
    }
  }
}
</style>
